package com.zhuangjie.rabbit.listen.wrap;

import com.rabbitmq.client.Channel;
import com.zhaungjie.base.utils.json.JsonUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

@Component
public abstract class MQListener<T> implements ChannelAwareMessageListener  {
    public abstract String listenQueue();


    /**
     * onMessage，如果重写该方法需要自动进行签收处理
     *
     * @param message 消息
     * @param channel 频道
     * @throws Exception 例外
     */
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            String type = ""+message.getMessageProperties().getHeader("__TypeId__");
            T data = (T)JsonUtils.parse(new String(message.getBody(), StandardCharsets.UTF_8),Class.forName(type));
            this.onMessageArrives(data);
            //3. 手动签收 , 如果解开
            channel.basicAck(deliveryTag,false);
        } catch (Exception e) {
            //4.拒绝签收
            /*
            第三个参数：requeue：重回队列。如果设置为true，则消息重新回到queue，broker会重新发送该消息给消费端
            如果没有签收就宕机了其实也会回收队列中的
             */
            channel.basicNack(deliveryTag,false,true);
            //channel.basicReject(deliveryTag,true);
        }
    }

    public abstract void onMessageArrives(T data) throws Exception;
}
